﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MoreEvent.Content.Biomes;
using System;
using Terraria;
using Terraria.Graphics.Effects;
using Terraria.ModLoader;
using Terraria.Utilities;

namespace MoreEvent.Content.Skies
{
    public class MeteorSky : CustomSky
    {
        private readonly UnifiedRandom random = new();
        private Texture2D meteorTexture;
        private bool isActive;       
        private Meteor[] meteors;
        private float fadeOpacity;
        public override void OnLoad()
        {
            meteorTexture = ModContent.Request<Texture2D>("MoreEvent/Assets/Images/Misc/Meteor2").Value;
        }
        public override void Update(GameTime gameTime)
        {
            fadeOpacity = !isActive ? Math.Max(0f, fadeOpacity - 0.01f) : Math.Min(1f, 0.01f + fadeOpacity);
            float num = 1200f;
            for (int i = 0; i < meteors.Length; i++)
            {
                Meteor[] array = meteors;
                int num2 = i;
                array[num2].Position.X = array[num2].Position.X - num * (float)gameTime.ElapsedGameTime.TotalSeconds;
                Meteor[] array2 = meteors;
                int num3 = i;
                array2[num3].Position.Y = array2[num3].Position.Y + num * (float)gameTime.ElapsedGameTime.TotalSeconds;
                if (meteors[i].Position.Y > Main.worldSurface * 16.0)
                {
                    meteors[i].Position.X = meteors[i].StartX;
                    meteors[i].Position.Y = -10000f;
                }
            }
        }
        private int SortMethod(Meteor meteor1, Meteor meteor2)
        {
            return meteor2.Depth.CompareTo(meteor1.Depth);
        }
        public override void Deactivate(params object[] args)
        {
            isActive = Main.LocalPlayer.InModBiome<MeteorShower>() && !Main.gameMenu;
        }
        public override void Reset()
        {
            isActive = false;
        }
        public override bool IsActive()
        {
            return isActive || fadeOpacity > 0.001;
        }
        public override float GetCloudAlpha()
        {
            return (float)((1.0 - fadeOpacity) * 0.300000011920929 + 0.699999988079071);
        }
        public override void Activate(Vector2 position, params object[] args)
        {
            fadeOpacity = 0.002f;
            isActive = true;
            meteors = new Meteor[50];
            for (int i = 0; i < meteors.Length; i++)
            {
                float num = i / (float)meteors.Length;
                meteors[i].Position.X = (float)((double)num * (Main.maxTilesX * 16.0) + (double)random.NextFloat() * 40.0 - 20.0);
                meteors[i].Position.Y = (float)((double)random.NextFloat() * -(float)(Main.worldSurface * 16.0 + 10000.0) - 10000.0);
                meteors[i].Depth = random.NextBool(3) ? (float)((double)random.NextFloat() * 5.0 + 4.80000019073486) : (float)((double)random.NextFloat() * 3.0 + 1.79999995231628);
                meteors[i].FrameCounter = random.Next(12);
                meteors[i].Scale = (float)((double)random.NextFloat() * 0.5 + 1.0);
                meteors[i].StartX = meteors[i].Position.X;
            }
            Array.Sort(meteors, new Comparison<Meteor>(SortMethod));
        }
        public override Color OnTileColor(Color inColor)
        {
            return new Color(Vector4.Lerp(inColor.ToVector4(), Vector4.One, fadeOpacity * 0.5f));
        }
        public override void Draw(SpriteBatch spriteBatch, float minDepth, float maxDepth)
        {
            if (Main.rand.NextBool(5))
            {
                meteorTexture = ModContent.Request<Texture2D>("MoreEvent/Assets/Images/Misc/Meteor").Value;
            }
            int num = -1;
            int num2 = 0;
            for (int i = 0; i < meteors.Length; i++)
            {
                float depth = meteors[i].Depth;
                if (num == -1 && (double)depth < (double)maxDepth)
                {
                    num = i;
                }
                if ((double)depth <= (double)minDepth)
                {
                    break;
                }
                num2 = i;
            }
            if (num == -1)
            {
                return;
            }
            float num3 = Math.Min(1f, (float)((Main.screenPosition.Y - 1000.0) / 1000.0));
            Vector2 vector = Main.screenPosition + new Vector2(Main.screenWidth >> 1, Main.screenHeight >> 1);
            Rectangle rectangle;
            rectangle = new(-1000, -1000, 4000, 4000);
            for (int j = num; j < num2; j++)
            {
                Vector2 vector2;
                vector2 = new(1f / meteors[j].Depth, 0.9f / meteors[j].Depth);
                Vector2 vector3 = (meteors[j].Position - vector) * vector2 + vector - Main.screenPosition;
                int num4 = meteors[j].FrameCounter / 3;
                meteors[j].FrameCounter = (meteors[j].FrameCounter + 1) % 12;
                if (rectangle.Contains((int)vector3.X, (int)vector3.Y))
                {
                    spriteBatch.Draw(meteorTexture, vector3, new Rectangle?(new Rectangle(0, num4 * (meteorTexture.Height / 4), meteorTexture.Width, meteorTexture.Height / 4)), Color.White * num3 * fadeOpacity, 0f, Vector2.Zero, vector2.X * 5f * meteors[j].Scale, 0, 0f);
                }
            }
        }
        private struct Meteor
        {
            public Vector2 Position;
            public float Depth;
            public int FrameCounter;
            public float Scale;
            public float StartX;
        }
    }
}
